import { Context, Schema, h } from 'koishi'
const fs = require('node:fs');

export const name = 'fuzzy-search-frontend'

// export interface Config { }

export const Config = Schema.intersect(
  [
    Schema.object(
      {
        DefaultAlsLimit: Schema.number().role('slider')
          .min(0).max(1000).step(1).default(30),
        MaxAlsLimit: Schema.number().role('slider')
          .min(0).max(1000).step(1).default(300),
        MinAlsLimit: Schema.number().role('slider')
          .min(0).max(1000).step(1).default(0),
        enableArgMsgHint: Schema.boolean()
          .default(false)
      }
    ).description("als-awa_list_file指令相关"),
    Schema.object(
      {
        mcicon_backend_address: Schema.string().default('localhost:8989').description("mc图标后端地址，ip+port"),
      }
    ).description("MCICON-后端服务相关"),
    Schema.object(
      {
        VerboseLoggerMode: Schema.boolean().default(false).description("是否开启详细输出")
      }
    ).description("DebugConfig-调试内容相关")
  ]
)

export function apply(ctx: Context, config) {

  ctx.command('als [arg0_path:string] [arg1_limit:number]', "als means \"awa_list_file\" 列出文件")
    .option('arg2_mode', '-m, --mode <arg2_mode:string> 输出模式: ascending, descending, random')
    .option('arg3_withimg', '-i, --image <arg3_withimg:boolean> 是否带图: true, false')
    .action(async ({ session, options }, arg0_path, arg1_limit) => {
      const sessionUser = await session.bot.getUser(session.userId, session.event.guild.id);
      const sessionGuildMember = await session.bot.getGuildMember(session.guildId, session.userId)


      const DEFAULT_ALS_LIMIT = config.DefaultAlsLimit;
      const MAX_ALS_LIMIT = config.MaxAlsLimit;
      const MIN_ALS_LIMIT = config.MinAlsLimit;
      const MODE_DESC_DICT = {
        "ascending": "升序排列",
        "descending": "降序排列",
        "random": "随机输出"
      }


      let als_path = arg0_path ? arg0_path : "❓没有输入";
      let als_limit = arg1_limit ? arg1_limit : "❓没有输入";
      let als_mode = options.arg2_mode ? options.arg2_mode : "❓没有输入";
      let als_withimg = options.arg3_withimg ? options.arg3_withimg : "❓没有输入";

      let msg_args = `📁path = ${als_path},\n📊limit = ${als_limit},\n⚙️mode = ${als_mode},\n🖼️withimg = ${als_withimg}`;

      msg_args += `\n\n🔵limit参数的范围是[${MIN_ALS_LIMIT}, ${MAX_ALS_LIMIT}]\n`;
      if (arg1_limit === undefined) {
        als_limit = DEFAULT_ALS_LIMIT;
        msg_args += `⚠️ 没有加limit参数，limit设为默认值${DEFAULT_ALS_LIMIT}条哈`
      } else {
        const limit_range = Math.max(MIN_ALS_LIMIT, Math.min(arg1_limit || DEFAULT_ALS_LIMIT, MAX_ALS_LIMIT)); // 默认值为 10
        // 如果 limit 被修改了，发送提示信息
        if (arg1_limit !== limit_range) {
          if (arg1_limit < MIN_ALS_LIMIT) {
            als_limit = DEFAULT_ALS_LIMIT;
            msg_args += `😱 limit输入了负数，已设为 ${DEFAULT_ALS_LIMIT}`;
          } else if (arg1_limit > MAX_ALS_LIMIT) {
            als_limit = MAX_ALS_LIMIT;
            msg_args += `🚨 limit输入了超出 ${MAX_ALS_LIMIT}，已设为 ${MAX_ALS_LIMIT}`;
          }
        }
      }

      await session.send(h.quote(session.messageId) + msg_args);


      // let url = "http://localhost:8989/ls";
      let url = `http://${config.mcicon_backend_address}/ls`;
      const params = new URLSearchParams();
      if (arg0_path && arg0_path !== '-') params.append("dir_path", als_path);
      // if (arg1_limit) params.append("limit", als_limit.toString());
      // 这里在append params的时候 判断是否传了limit参数，区别于下面的afs
      params.append("limit", als_limit.toString());
      if (options.arg2_mode && als_mode !== '-') params.append("mode", als_mode);

      if (params.toString()) url += `?${params.toString()}`;

      if (config.VerboseLoggerMode)
        await session.send(h.quote(session.messageId) + `[debug]\nhttp request url = ${url}`);

      const result = await ctx.http.get(url)
        .then(async (res) => {
          // ctx.logger.info(res.data);
          ctx.logger.info(JSON.stringify(res.data).slice(0, 50));

          if (res.code !== 200) {
            await session.send(`错误, code!=200: ${res.message}`);
            return;
          }

          const data = res.data;
          const items = data.items;

          const treeLines: string[] = [];
          // treeLines.push(`📂 ${data.current_path}`);

          for (const item of items) {
            const prefix = item.type === "directory" ? "📁" : "📄";
            let line_msg = ` ├── ${prefix} ${item.name}`;
            if (als_withimg === true && item.type !== "directory") {
              // line_msg += h.image(`http://localhost:8989/mcimg/${als_path}/${item.name}`);
              line_msg += h.image(`http://${config.mcicon_backend_address}/mcimg/${als_path}/${item.name}`);
            }


            treeLines.push(line_msg);
          }

          let msg_treeLines = "";
          msg_treeLines += `
            <message>
              <author name="afs的输出："/>
                🔍 列文件结果 
            </message>
          `;

          const PAGE_LEN = 10;
          const total_page_num = Math.ceil(
            ((typeof als_limit) === "number" ? als_limit : DEFAULT_ALS_LIMIT) / PAGE_LEN
          );
          ctx.logger.info(`als_limit = ${als_limit}`);
          for (let i = 1; i <= total_page_num; i++) {
            let l = 0 + (i - 1) * PAGE_LEN, r = l + PAGE_LEN - 1; //[l,r] 是下标范围，都是闭区间
            ctx.logger.info(`i=${i}, l=${l}, r=${r}, total_page_num=${total_page_num}`);
            ctx.logger.info(treeLines.slice(l + 1, r + 2));
            msg_treeLines += `
              <message>
                <author name="afs的输出："/>
                  ↓ Page: (${i} / ${total_page_num}) ↓
              </message>
              <message>
                <author name="Page: (${i} / ${total_page_num})"/>
                <p>📂 ${data.current_path}</p>
                ${(i > 1) ? "</p> ├── .....<p>" : ""}
                ${treeLines.slice(l, r + 1).map(line => `<p>${line}</p>`).join("\n")}
                ${(i < total_page_num) ? "<p> ├── .....</p>" : ""}</p>
              </message>
              `;
          }

          msg_treeLines += `
              <message>
                <author name="afs的输出："/>
                <p><b>日期:   </b>\t ${new Date().toLocaleString()} \n </p>
                <p><b>调用者: </b>\t ${sessionUser.name} ( ${sessionGuildMember.nick} )</p>\n `
            + h.image(sessionUser.avatar) + `
              </message>
          `;

          //包装成合并转发
          msg_treeLines = `<message forward>\n` + msg_treeLines + `</message>\n`;

          await session.send(h.unescape(msg_treeLines));

        })
        .catch(async (err) => {
          ctx.logger.error(err);
        })


    })

  ctx.command('afs <arg0_keyword:string> [arg1_limit:number]', "afs means \"awa_fuzzy_search\"模糊搜索")
    .option('arg3_withimg', '-i, --image <arg3_withimg:boolean> 是否带图: true, false')
    .action(async ({ session, options }, arg0_keyword, arg1_limit) => {
      const sessionUser = await session.bot.getUser(session.userId, session.event.guild.id);
      const sessionGuildMember = await session.bot.getGuildMember(session.guildId, session.userId)

      const DEFAULT_AFS_LIMIT = 30;
      const DEFAULT_AFS_KEYWORD = "水泥浆糊";
      const MAX_AFS_LIMIT = 100;
      const MIN_AFS_LIMIT = 0;

      const afs_keyword = arg0_keyword ? arg0_keyword : "❓没有输入";
      const afs_limit = arg1_limit ? arg1_limit : "❓没有输入";
      const afs_withimg = options.arg3_withimg ? options.arg3_withimg : "❓没有输入"

      let msg_args = `🔍keyword = ${afs_keyword},\n📊limit = ${afs_limit},\n🖼️withimg = ${afs_withimg}\n`;
      msg_args += `---------\n`

      if (arg0_keyword === undefined) {
        msg_args += `\n⚠️ 没有传搜索关键词，keyword fallback到'${DEFAULT_AFS_KEYWORD}'.\n`;
      }

      msg_args += `\n🔵limit参数的范围是[${MIN_AFS_LIMIT}, ${MAX_AFS_LIMIT}]\n`;
      if (arg1_limit === undefined) {
        // afs_limit = DEFAULT_AFS_LIMIT;
        msg_args += `⚠️ 没有加limit参数，limit设为默认值${DEFAULT_AFS_LIMIT}哈`
      } else {
        const limit_range = Math.max(MIN_AFS_LIMIT, Math.min(arg1_limit || DEFAULT_AFS_LIMIT, MAX_AFS_LIMIT)); // 默认值为 10
        // 如果 limit 被修改了，发送提示信息
        if (arg1_limit !== limit_range) {
          if (arg1_limit < MIN_AFS_LIMIT) {
            msg_args += `😱 limit输入了负数，已设为 10`;
          } else if (arg1_limit > MAX_AFS_LIMIT) {
            msg_args += `🚨 limit输入了超出 ${MAX_AFS_LIMIT}，已设为 ${MAX_AFS_LIMIT}`;
          }
        }
      }

      if ( config.enableArgMsgHint )
        await session.send(h.quote(session.messageId) + msg_args);

      // let url = "http://localhost:8989/fuzzy_guess";
      let url = `http://${config.mcicon_backend_address}/fuzzy_guess`;
      const params = new URLSearchParams();
      params.append("keyword", arg0_keyword === undefined ? DEFAULT_AFS_KEYWORD : afs_keyword);
      params.append("limit", arg1_limit === undefined ? DEFAULT_AFS_LIMIT.toString() : afs_limit.toString());

      if (params.toString()) url += `?${params.toString()}`;

      if (config.VerboseLoggerMode)
        await session.send(h.quote(session.messageId) + `[debug]\nhttp request url = ${url}`);

      try {
        const result = await ctx.http.get(url);
        // 在这里检查返回数据的结构并打印
        ctx.logger.info(result); // 直接查看返回的完整响应

        if (result.code !== 200) {
          await session.send(`错误, code!=200: ${result.message}`);
          return;
        }

        // 获取搜索结果
        const data = result.data;
        const results = data.results; // 假设返回的数据包含一个 'results' 数组

        let msg = "";

        if (results.length === 0) {
          // await session.send(`没有找到符合条件的结果。`);
          msg += `没有找到符合条件的结果。`;
        } else {
          const resultLines: string[] = [];
          results.forEach((item, index) => {

            const formattedIndex = String(index + 1).padStart(2, "0");
            let line_msg = '';
            //line_msg += ` ${index + 1}. ${item.name} (score: ${item.score})`
            line_msg += ` ${formattedIndex}.${'⭐'.repeat(item.score)} (相似度：${item.score}) \n\t 📌 ${item.name} `;
            // ctx.logger.info(item.name);
            if (afs_withimg === true) {
              // line_msg += h.image(`http://localhost:8989/mcimg/${item.name.toString().replace(/\\/g, "/")}`);
              line_msg += h.image(`http://${config.mcicon_backend_address}/mcimg/${item.name.toString().replace(/\\/g, "/")}`);
            }
            resultLines.push(line_msg);

          });
          // await session.send(resultLines.join("\n"));

          let msg_resultlines = "";
          msg_resultlines += `
            <message>
              <author name="afs的输出："/>
                🔍 搜索结果 
            </message>
          `;

          const PAGE_LEN = 10;
          const total_page_num = 1 + (arg1_limit ? arg1_limit : DEFAULT_AFS_LIMIT) / PAGE_LEN;
          for (let i = 1; i <= total_page_num; i++) {
            let l = 0 + (i - 1) * PAGE_LEN, r = l + PAGE_LEN - 1; //[l,r] 是下标范围，都是闭区间
            ctx.logger.info(`i=${i}, l=${l}, r=${r}, total_page_num=${total_page_num}`);
            ctx.logger.info(resultLines.slice(l + 1, r + 2));
            msg_resultlines += `
              <message>
                <author name="afs的输出："/>
                  ↓ Page: (${i} / ${total_page_num}) ↓
              </message>
              <message>
                <author name="Page: (${i} / ${total_page_num})"/>
                ${resultLines.slice(l, r + 1).join("\n")} 
              </message>
              `;
          }


          msg_resultlines += `
              <message>
                <p><b>日期:   </b>\t ${new Date().toLocaleString()} \n </p>
                <p><b>调用者: </b>\t ${sessionUser.name} ( ${sessionGuildMember.nick} )</p>\n `
            + h.image(sessionUser.avatar) + `
              </message>
          `;

          //包装成合并转发
          msg_resultlines = `<message forward>\n` + msg_resultlines + `</message>\n`;
          await session.send(h.unescape(msg_resultlines));

          // await session.send(h.image(session_user.avatar))
        }
      } catch (err) {
        ctx.logger.error(err);
        await session.send(`请求失败: ${err.message}`);
      }


    });


}
